package invite_controller

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"shimmer/neusoft_club_backend/controllers/cons"
	"shimmer/neusoft_club_backend/dao/domain"
	"shimmer/neusoft_club_backend/middlewares/auth_middleware"
	"shimmer/neusoft_club_backend/services"
	"shimmer/neusoft_club_backend/services/club_service"
	"shimmer/neusoft_club_backend/services/errs"
	"shimmer/neusoft_club_backend/services/invite_service"
)

// @Summary 查询邀请链接信息
// @Description 能得到邀请链接ID,社团信息,邀请人信息
// @Tags 邀请链接
// @Param inviteID path integer true "邀请ID"
// @Success 200 {object} domain.ClubInviteLinkDTO
// @Router /api/invite/{inviteID} [get]
func findInviteLink(c *gin.Context) {
	inviteBinding := &cons.InviteUriParamBinding{}
	if err := c.ShouldBindUri(inviteBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	res, err := invite_service.FindInviteLinkByID(inviteBinding.InviterID)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.JSON(http.StatusOK, res)
}

// @Summary 使用邀请链接
// @Description 使用邀请链接后直接加入社团
// @Tags 邀请链接
// @Param inviteID path integer true "邀请ID"
// @Param inviteParam body invite_service.InviteLinkParameters true "使用邀请链接必备参数"
// @Success 204
// @Router /api/invite/{inviteID} [post]
func useInviteLink(c *gin.Context) {
	user, err := domain.GetUserFromContext(c)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}

	parameters := &invite_service.InviteLinkParameters{}
	if err = c.ShouldBind(parameters); err != nil {
		services.AbortWithError(c, err)
		return
	}
	inviteBinding := &cons.InviteUriParamBinding{}
	if err = c.ShouldBindUri(inviteBinding); err != nil {
		services.AbortWithError(c, err)
		return
	}
	valid, err := invite_service.ValidateInviteSignature(parameters)
	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	if !valid {
		services.AbortWithError(c, errs.ErrInvalidInvite)
		return
	}
	err = club_service.InviteUserJoinClubImmediately(inviteBinding.InviterID, user.ID, parameters.ClubID)

	if err != nil {
		services.AbortWithError(c, err)
		return
	}
	c.AbortWithStatus(http.StatusNoContent)
}

func ConfigInviteController(r *gin.RouterGroup) {
	r.GET(fmt.Sprintf("/:%s", cons.InviteParam), findInviteLink)
	r.POST(fmt.Sprintf("/:%s", cons.InviteParam), auth_middleware.AuthLoginMiddleware(), useInviteLink)
}
